/*
 *HttpServer.java
 *˵����
 *Created by Sky on2015/7/8
 *Copyright(c)2015 Sky All Rights Reserved
 */
package com.zhs.gccs.mbtiles.server;


import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

//import com.zhs.gccs.mbtiles.AppDataManager;
//import com.zhs.gccs.mbtiles.AppDatabase;
//import com.zhs.gccs.mbtiles.Tiles;

import com.zhs.gccs.mbtiles.Tiles;
import com.zhs.gccs.dao.TilesDao;
import com.zhs.gccs.model.SmTask;
import com.zhs.gccs.utils.FileUtils;
import com.zhs.gccs.utils.Utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;

//本地 类似geoserver rest  http://localhost:9999/mbtile?model=gd&type=png&layer=0103&x={x}&y={y}&z={z}
public class MapboxHttpServer implements Runnable {
    private Context context;
    private int port = 9999;
    String contentHeader = "Content-Length:";
    String HTTPProtocal = "HTTP/1.1";
    String acceptencoding = "Accept-Encoding:";
    private Thread httpServerThread;
//    private TilesDao tilesDao;
    private ServerSocket serverSocket;

    private boolean isRunning = false;
    private SmTask smTask;
    private TilesDao tilesDao;

    public MapboxHttpServer(SmTask smTask) {
        this.smTask = smTask;

    }

    public void startServer(Context context) {
        this.context = context;
        this.tilesDao = new TilesDao(Utils.getTaskRootFolder(context,smTask));
        this.httpServerThread = new Thread(this);
        this.isRunning = true;
        this.httpServerThread.start();
        try {
            this.serverSocket = new ServerSocket(this.port);
        } catch (IOException e) {
            Log.e("MapboxHttpServer",e.getMessage());
        }
    }

    public void stopServer(Context context){
        try {
            this.isRunning = true;
            if(this.serverSocket!=null){
                this.serverSocket.close();
            }
        } catch (IOException e) {
            Log.e("MapboxHttpServer",e.getMessage());
        }
    }

    public void run() {
        try {
            do {
                Socket socket = null;
                try {
                    socket = serverSocket.accept();
                    if(socket!=null){
                        System.out.println(">>>Current Thread[MapboxHttpServer]:" + Thread.currentThread().getName());
                        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
                        String line = null;
                        int contentLength = 0;
                        String httpMethod = null, url = null, encoding = null;
                        while (!TextUtils.isEmpty(line = reader.readLine())) {
                            System.out.println(">>>input header:" + line);
                            if (line.startsWith(contentHeader)) {
                                contentLength = Integer.parseInt(line.replace(contentHeader, "").trim());
                            } else if (line.contains(HTTPProtocal)) {
                                String[] httpM = line.split(" ");
                                httpMethod = httpM[0];
                                url = httpM[1];
                            } else if (line.contains(acceptencoding)) {
                                encoding = line.replace(acceptencoding, "").trim();
                            }
                        }
                        //请求体
                        StringBuilder body = new StringBuilder();
                        for (int i = 0; i < contentLength; i++) {
                            int c = reader.read();
                            body.append((char) c);
                        }
                        OutputStream out = socket.getOutputStream();
                        WmsParam wmsParam = RequestParamParser.parseParam(url, httpMethod, URLDecoder.decode(body.toString(), "UTF-8"));
                        if (wmsParam != null && !TextUtils.isEmpty(wmsParam.getModel())
                                && !TextUtils.isEmpty(wmsParam.getType())) {
                            if (WmsParam.type_mbtile.equalsIgnoreCase(wmsParam.getType())) {
                                // (int) (Math.pow(2,wmsParam.getY())-1-wmsParam.getY())
                                Tiles tiles = tilesDao.find(context,wmsParam.getModel(),wmsParam.getLayer(),
                                        wmsParam.getX(), wmsParam.getY(), wmsParam.getZ());
                                if (tiles != null && tiles.getData() != null) {
                                    if(WmsParam.type_pbf.equalsIgnoreCase(tiles.getType())){
                                        ResponseResolver.responseByteSuccess(out, "application/x-protobuf", encoding, tiles.getData());
                                    }else if(WmsParam.type_png.equalsIgnoreCase(tiles.getType())){
                                        ResponseResolver.responseByteSuccess(out, "image/png", null, tiles.getData());
                                    }else if(WmsParam.type_jpeg.equalsIgnoreCase(tiles.getType())){
                                        ResponseResolver.responseByteSuccess(out, "image/jpeg", null, tiles.getData());
                                    }else if(WmsParam.type_jpg.equalsIgnoreCase(tiles.getType())){
                                        ResponseResolver.responseByteSuccess(out, "image/jpg", null, tiles.getData());
                                    }else {
                                        ResponseResolver.responseByteSuccess(out, "application/x-protobuf", encoding, tiles.getData());
                                    }
                                } else {
                                    Log.e("MapboxHttpServer", "InputStream read no data");
                                    ResponseResolver.responseError(socket.getOutputStream(), "数据不存在");
                                }
                            }
                            else if (WmsParam.type_pbf.equalsIgnoreCase(wmsParam.getType())) {
                                File file = new File(Utils.getMainPath(context) +
                                        wmsParam.getModel()+"/"+wmsParam.getLayer()+"/"+wmsParam.getZ()+"/"+wmsParam.getX(),  wmsParam.getY() + ".pbf");
                                byte[] bytes = FileUtils.readFileToByteArray(file);
//                            if(bytes!=null){
//                                Log.d("MapboxHttpServer","found: "+url);
//                            }
                                ResponseResolver.responseByteSuccess(out, "application/x-protobuf", encoding, bytes);
                            }
                            else if (WmsParam.type_wvt.equalsIgnoreCase(wmsParam.getType())) {
                                File file = new File(Utils.getMainPath(context) +
                                        wmsParam.getModel()+"/"+wmsParam.getLayer()+"/"+wmsParam.getZ()+"/"+wmsParam.getX(),  wmsParam.getY() + ".mvt");
                                byte[] bytes = FileUtils.readFileToByteArray(file);
//                            if(bytes!=null){
//                                Log.d("MapboxHttpServer","found: "+url);
//                            }
                                ResponseResolver.responseByteSuccess(out, "application/vnd.mapbox-vector-tile", encoding, bytes);
                            }
                            else if (WmsParam.type_png.equalsIgnoreCase(wmsParam.getType())) {
                                File file = new File(Utils.getMainPath(context) +
                                        wmsParam.getModel()+"/"+wmsParam.getLayer()+"/" + wmsParam.getZ() + "/" + wmsParam.getX(), wmsParam.getY() + ".png");
                                byte[] bytes = FileUtils.readFileToByteArray(file);
                                //照片不用压缩
                                ResponseResolver.responseByteSuccess(out, "image/png", null, bytes);
                            }
                            else if (WmsParam.type_jpeg.equalsIgnoreCase(wmsParam.getType())) {
                                File file = new File(Utils.getMainPath(context) +
                                        wmsParam.getModel()+"/"+wmsParam.getLayer()+"/" + wmsParam.getZ() + "/" + wmsParam.getX(), wmsParam.getY() + ".jpeg");
                                byte[] bytes = FileUtils.readFileToByteArray(file);
//                            if(bytes!=null){
//                                Log.d("MapboxHttpServer","found: "+url);
//                            }
                                ResponseResolver.responseByteSuccess(out, "image/jpeg", null, bytes);
                            }
                            else if (WmsParam.type_jpg.equalsIgnoreCase(wmsParam.getType())) {
                                File file = new File(Utils.getMainPath(context) +
                                        wmsParam.getModel()+"/"+wmsParam.getLayer()+"/" + wmsParam.getZ() + "/" + wmsParam.getX(), wmsParam.getY() + ".jpg");
                                byte[] bytes = FileUtils.readFileToByteArray(file);
//                            if(bytes!=null){
//                                Log.d("MapboxHttpServer","found: "+url);
//                            }
                                ResponseResolver.responseByteSuccess(out, "image/jpg", null, bytes);
                            }else {
                                ResponseResolver.responseError(socket.getOutputStream(), "参数类型错误");
                            }
                        }else {
                            ResponseResolver.responseError(socket.getOutputStream(), "参数错误");
                        }
                    }
                } catch (Exception e) {
                    Log.e("MapboxHttpServer", "InputStream read failed" + e.toString());
                    try {
                        if(socket!=null){
                            ResponseResolver.responseError(socket.getOutputStream(), "");
                        }
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
            } while (isRunning&&!serverSocket.isClosed());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
